/*
 * @Author: LVGRAPE
 * @Date: 2023-11-09 11:26:41
 * @LastEditTime: 2023-11-15 11:46:02
 * @LastEditors: LVGRAPE
 * @Description:
 * @FilePath: \zino_fc_v0\zino\power\battery_led.c
 * 要啥没啥，爱咋咋的
 */
#if !defined(ZINO_I)

#include "zino.h"

#define DBG_TAG "bled"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#define IS_VIN_PLUG_IN() IO_Read(PC13) /**USB 充电插入,插入时为1 */

// typedef struct
// {
// 	GPIO_Type *port;
// 	uint16_t pins;		   /*!< Specifies the GPIO pins to be configured.
// 									This parameter can be any value of @ref GPIO_pins_define */
// 	GPIOMaxSpeed_Type speed; /*!< Specifies the speed for the selected pins.
// 									   This parameter can be a value of @ref GPIOMaxSpeed_Type */
// 	GPIOMode_Type mode;			   /*!< Specifies the operating mode for the selected pins.
// 										  This parameter can be a value of @ref GPIOMode_Type */
// }__zino_io_t;
typedef struct
{
	// __zino_io_t LED1;
	// __zino_io_t LED2;
	// __zino_io_t LED3;
	zino_io_t LED1;
	zino_io_t LED2;
	zino_io_t LED3;
} ZINO_PWR_LEDS_T;
static ZINO_PWR_LEDS_T zinoPWR_LED_PINs = {
	.LED1 = {.port = GPIOB, .pin = GPIO_Pins_3 },
	.LED2 = {.port = GPIOB, .pin = GPIO_Pins_4 },
	.LED3 = {.port = GPIOB, .pin = GPIO_Pins_5 },
};
/**
 * @brief 设置IO 模式
 *
 * @param pin __zino_io_t
 * @param mode one of GPIOMode_Type:
 * GPIO_Mode_IN_ANALOG
 * GPIO_Mode_IN_FLOATING
 * GPIO_Mode_IN_PD
 * GPIO_Mode_IN_PU
 * GPIO_Mode_OUT_OD
 * GPIO_Mode_AF_PP
 */
// void zino_pin_mode(__zino_io_t *pin, GPIOMode_Type mode)
// {
// 	GPIO_InitType ioInit;
// 	pin->mode = mode;
// 	ioInit.GPIO_Pins = pin->pins;
// 	ioInit.GPIO_MaxSpeed = pin->speed;
// 	ioInit.GPIO_Mode = pin->mode;
// 	GPIO_Init(pin->port, &ioInit);
// }
/**
 * @brief 点亮一个LED, 并且关闭其它LED
 *
 * @param led 要点点亮的LED:1、2、3、4。0：关闭所有LED
 */
void zinoPwrLedOn(uint8_t led)
{
    
	switch (led)
	{

	case 0:
		zino_pin_mode(&zinoPWR_LED_PINs.LED1, GPIO_Mode_IN_FLOATING);
		zino_pin_mode(&zinoPWR_LED_PINs.LED2, GPIO_Mode_IN_FLOATING);
		zino_pin_mode(&zinoPWR_LED_PINs.LED3, GPIO_Mode_IN_FLOATING);
		break;
	case 1:
		zino_pin_mode(&zinoPWR_LED_PINs.LED1, GPIO_Mode_OUT_PP);
		zino_pin_mode(&zinoPWR_LED_PINs.LED2, GPIO_Mode_IN_FLOATING);
		zino_pin_mode(&zinoPWR_LED_PINs.LED3, GPIO_Mode_OUT_PP);

		zino_pin_high(&zinoPWR_LED_PINs.LED1);
		zino_pin_low(&zinoPWR_LED_PINs.LED3);

		// GPIO_SetBits((GPIO_Type *)zinoPWR_LED_PINs.LED1.port, zinoPWR_LED_PINs.LED1.pins);
		// GPIO_ResetBits((GPIO_Type *)zinoPWR_LED_PINs.LED3.port, zinoPWR_LED_PINs.LED3.pins);
		break;
	case 2:
		zino_pin_mode(&zinoPWR_LED_PINs.LED1, GPIO_Mode_OUT_PP);
		zino_pin_mode(&zinoPWR_LED_PINs.LED2, GPIO_Mode_IN_FLOATING);
		zino_pin_mode(&zinoPWR_LED_PINs.LED3, GPIO_Mode_OUT_PP);

		// GPIO_SetBits(zinoPWR_LED_PINs.LED3.port, zinoPWR_LED_PINs.LED3.pins);
		// GPIO_ResetBits(zinoPWR_LED_PINs.LED1.port, zinoPWR_LED_PINs.LED1.pins);
		zino_pin_high(&zinoPWR_LED_PINs.LED3);
		zino_pin_low(&zinoPWR_LED_PINs.LED1);
		break;
	case 3:
		zino_pin_mode(&zinoPWR_LED_PINs.LED1, GPIO_Mode_IN_FLOATING);
		zino_pin_mode(&zinoPWR_LED_PINs.LED2, GPIO_Mode_OUT_PP);
		zino_pin_mode(&zinoPWR_LED_PINs.LED3, GPIO_Mode_OUT_PP);

		zino_pin_high(&zinoPWR_LED_PINs.LED2);
		zino_pin_low(&zinoPWR_LED_PINs.LED3);
		// GPIO_SetBits((GPIO_Type *)zinoPWR_LED_PINs.LED2.port, zinoPWR_LED_PINs.LED2.pins);
		// GPIO_ResetBits((GPIO_Type *)zinoPWR_LED_PINs.LED3.port, zinoPWR_LED_PINs.LED3.pins);
		break;
	case 4:
		zino_pin_mode(&zinoPWR_LED_PINs.LED1, GPIO_Mode_IN_FLOATING);
		zino_pin_mode(&zinoPWR_LED_PINs.LED2, GPIO_Mode_OUT_PP);
		zino_pin_mode(&zinoPWR_LED_PINs.LED3, GPIO_Mode_OUT_PP);

		// GPIO_ResetBits((GPIO_Type *)zinoPWR_LED_PINs.LED2.port, zinoPWR_LED_PINs.LED2.pins);
		// GPIO_SetBits((GPIO_Type *)zinoPWR_LED_PINs.LED3.port, zinoPWR_LED_PINs.LED3.pins);
		zino_pin_high(&zinoPWR_LED_PINs.LED3);
		zino_pin_low(&zinoPWR_LED_PINs.LED2);
		break;

	default:
		break;
	}
}
/**
 * @brief 接管下板3线4灯电量灯
 * 原理：IO浮空时灯不亮，从而实现一次只点一个灯。
 * 4个灯循环点亮，只要循环时间够快，人眼里的残影看起来4个都点亮了。
 */
void pwrLedHandle(void *p)
{
	static uint8_t ledCnt;
	static uint16_t cycleCnt;
	static uint8_t ledCntMax;
	static uint8_t ledSet;
	static bool lowVoltageWarningFlag = 0;
	uint16_t blinkTime;
	static uint32_t blinkT;
	static uint32_t vbatFullT;
	// rt_kprintf("5V:%dmV\n",zino_get_vbat());

	int16_t vbat = zino_get_vbat();
	int16_t v5 = zino_get_v5();
// int16_t v5 = 4800;

/**计算要点亮多少个LED:
 * 0~3.3V 1个,
 * 3.3~3.6V 2个,
 * 3.6~3.9V 3个,
 * 3.9~4.2V 4个
 * */
#ifdef HeartOfMecha
	ledSet = (vbat > 3300) ? ((vbat - 3300) / 225 + 1) : 0;
#elif Excavator
	ledSet = (vbat > 3300) ? ((vbat - 3300) / 225 + 1) : 0;
#elif WingOfSky

	if (!FC_ERROR_CHECK(FC_ARMED))
	{
		// if (vbat > 3600)
		vbat -= 300;
		if (vbat <= 3200)
			vbat = 3200;
	}
	// 	ledSet = (vbat > 3300) ? ((vbat - 3300) / 225 + 1) : 0;
	// else
	ledSet = (vbat > 3200) ? ((vbat - 3200) / 100 + 1) : 0;
	// ledSet = (vbat - 3200 - 600) / 100 + 1;
	if (ledSet > 4)
		ledSet = 4;
#else 
    ledSet = (vbat > 3300) ? ((vbat - 3300) / 225 + 1) : 0;   
#endif
	if (vbat < 3300)
	{
		/**低电压，快闪 */
		blinkTime = 250;
		lowVoltageWarningFlag = 1;
	}
	else
	{
		/**充电时，慢闪 */
		blinkTime = 500;
		lowVoltageWarningFlag = 0;
	}
	if (++cycleCnt > 1) /**LED 轮循周期，越大频闪越严重*/
	{
		cycleCnt = 0;
		ledCnt++;
		if (ledCnt > ledCntMax)
		{
			ledCnt = 0;
		}
	}
	if (IS_VIN_PLUG_IN() || lowVoltageWarningFlag)
	{
		/**最后一个LED闪烁 */
		if (millis() > blinkT + blinkTime)
		{
			ledCntMax = (ledSet > 0) ? (ledSet - 1) : 0;
		}
		else
		{
			ledCntMax = ledSet;
		}
		if (millis() > blinkT + blinkTime * 2)
		{
			blinkT = millis();
		}
	}
	else
	{
		if (v5 < 4900) // 5V升压失败时
		{
			if (millis() > blinkT + blinkTime / 2)
			{
				blinkT = millis();
				if (ledCntMax-- <= 0)
				{
					ledCntMax = ledSet;
				}
			}
		}
		else
		{
			ledCntMax = ledSet;
		}
	}
    // LOG_D("ledCnt:%d\n",ledCnt);
	zinoPwrLedOn(ledCnt); /**LED轮循点亮 */
}
int batteryLedInit(void)
{
    static os_timer_t batteryLedTimer;
    os_timer_init(&batteryLedTimer,pwrLedHandle,0);
    os_timer_start(&batteryLedTimer, 1,1);
    LOG_I("battery led init...\n");
    return 0;
}
ZINO_APP_EXPORT(batteryLedInit);
#endif
